Skip to content

Conversation

@octoper
Copy link
Member

@octoper octoper commented Jan 20, 2026

Description

This PR introduces the the screens and functionality for the new setup-mfa session task
If an instance has "Require multi-factor authentication" enabled, every user that does not have have MFA setup they will required to set it up on their next sign-in, also user that sign-up they will be prompted right away to perform the session task.

Sign up

CleanShot.2026-02-02.at.20.01.53.mp4

Sign in

CleanShot.2026-02-02.at.20.04.53.mp4

With other tasks

CleanShot.2026-02-02.at.20.06.27.mp4

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features
    • Introduced a "setup_mfa" session task and a TaskSetupMFA UI flow (SMS and authenticator/TOTP) with phone registration, selection, verification, and backup codes; new sandbox route to preview it.
  • Tests
    • Added end-to-end integration tests covering MFA setup happy paths, errors, navigation and back/cancel flows.
  • Documentation
    • Expanded localization strings across many locales for the MFA setup flows and related alerts.

@changeset-bot
Copy link

changeset-bot bot commented Jan 20, 2026

🦋 Changeset detected

Latest commit: ec92505

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 20 packages
Name Type
@clerk/tanstack-react-start Minor
@clerk/localizations Minor
@clerk/react-router Minor
@clerk/clerk-js Minor
@clerk/nextjs Minor
@clerk/shared Minor
@clerk/react Minor
@clerk/ui Minor
@clerk/chrome-extension Patch
@clerk/expo Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/msw Patch
@clerk/nuxt Patch
@clerk/testing Patch
@clerk/vue Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link

vercel bot commented Jan 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Feb 3, 2026 0:48am

Request Review

@octoper
Copy link
Member Author

octoper commented Jan 21, 2026

!snapshot

@clerk-cookie
Copy link
Collaborator

Hey @octoper - the snapshot version command generated the following package versions:

Package Version
@clerk/agent-toolkit 0.2.9-snapshot.v20260121104441
@clerk/astro 3.0.0-snapshot.v20260121104441
@clerk/backend 3.0.0-snapshot.v20260121104441
@clerk/chrome-extension 3.0.0-snapshot.v20260121104441
@clerk/clerk-js 6.0.0-snapshot.v20260121104441
@clerk/dev-cli 1.0.0-snapshot.v20260121104441
@clerk/expo 3.0.0-snapshot.v20260121104441
@clerk/expo-passkeys 1.0.0-snapshot.v20260121104441
@clerk/express 2.0.0-snapshot.v20260121104441
@clerk/fastify 2.6.9-snapshot.v20260121104441
@clerk/localizations 4.0.0-snapshot.v20260121104441
@clerk/msw 0.0.1-snapshot.v20260121104441
@clerk/nextjs 7.0.0-snapshot.v20260121104441
@clerk/nuxt 2.0.0-snapshot.v20260121104441
@clerk/react 6.0.0-snapshot.v20260121104441
@clerk/react-router 3.0.0-snapshot.v20260121104441
@clerk/shared 4.0.0-snapshot.v20260121104441
@clerk/tanstack-react-start 1.0.0-snapshot.v20260121104441
@clerk/testing 2.0.0-snapshot.v20260121104441
@clerk/ui 1.0.0-snapshot.v20260121104441
@clerk/upgrade 2.0.0-snapshot.v20260121104441
@clerk/vue 2.0.0-snapshot.v20260121104441

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/agent-toolkit

npm i @clerk/agent-toolkit@0.2.9-snapshot.v20260121104441 --save-exact

@clerk/astro

npm i @clerk/astro@3.0.0-snapshot.v20260121104441 --save-exact

@clerk/backend

npm i @clerk/backend@3.0.0-snapshot.v20260121104441 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@3.0.0-snapshot.v20260121104441 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@6.0.0-snapshot.v20260121104441 --save-exact

@clerk/dev-cli

npm i @clerk/dev-cli@1.0.0-snapshot.v20260121104441 --save-exact

@clerk/expo

npm i @clerk/expo@3.0.0-snapshot.v20260121104441 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@1.0.0-snapshot.v20260121104441 --save-exact

@clerk/express

npm i @clerk/express@2.0.0-snapshot.v20260121104441 --save-exact

@clerk/fastify

npm i @clerk/fastify@2.6.9-snapshot.v20260121104441 --save-exact

@clerk/localizations

npm i @clerk/localizations@4.0.0-snapshot.v20260121104441 --save-exact

@clerk/msw

npm i @clerk/msw@0.0.1-snapshot.v20260121104441 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@7.0.0-snapshot.v20260121104441 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@2.0.0-snapshot.v20260121104441 --save-exact

@clerk/react

npm i @clerk/react@6.0.0-snapshot.v20260121104441 --save-exact

@clerk/react-router

npm i @clerk/react-router@3.0.0-snapshot.v20260121104441 --save-exact

@clerk/shared

npm i @clerk/shared@4.0.0-snapshot.v20260121104441 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@1.0.0-snapshot.v20260121104441 --save-exact

@clerk/testing

npm i @clerk/testing@2.0.0-snapshot.v20260121104441 --save-exact

@clerk/ui

npm i @clerk/ui@1.0.0-snapshot.v20260121104441 --save-exact

@clerk/upgrade

npm i @clerk/upgrade@2.0.0-snapshot.v20260121104441 --save-exact

@clerk/vue

npm i @clerk/vue@2.0.0-snapshot.v20260121104441 --save-exact

@octoper octoper force-pushed the octoper/setup-mfa-task branch from 4fc95f2 to 61862a2 Compare January 22, 2026 11:04
@octoper
Copy link
Member Author

octoper commented Jan 22, 2026

!snapshot

@clerk-cookie
Copy link
Collaborator

Hey @octoper - the snapshot version command generated the following package versions:

Package Version
@clerk/agent-toolkit 0.2.9-snapshot.v20260122110524
@clerk/astro 3.0.0-snapshot.v20260122110524
@clerk/backend 3.0.0-snapshot.v20260122110524
@clerk/chrome-extension 3.0.0-snapshot.v20260122110524
@clerk/clerk-js 6.0.0-snapshot.v20260122110524
@clerk/dev-cli 1.0.0-snapshot.v20260122110524
@clerk/expo 3.0.0-snapshot.v20260122110524
@clerk/expo-passkeys 1.0.0-snapshot.v20260122110524
@clerk/express 2.0.0-snapshot.v20260122110524
@clerk/fastify 2.6.9-snapshot.v20260122110524
@clerk/localizations 4.0.0-snapshot.v20260122110524
@clerk/msw 0.0.1-snapshot.v20260122110524
@clerk/nextjs 7.0.0-snapshot.v20260122110524
@clerk/nuxt 2.0.0-snapshot.v20260122110524
@clerk/react 6.0.0-snapshot.v20260122110524
@clerk/react-router 3.0.0-snapshot.v20260122110524
@clerk/shared 4.0.0-snapshot.v20260122110524
@clerk/tanstack-react-start 1.0.0-snapshot.v20260122110524
@clerk/testing 2.0.0-snapshot.v20260122110524
@clerk/ui 1.0.0-snapshot.v20260122110524
@clerk/upgrade 2.0.0-snapshot.v20260122110524
@clerk/vue 2.0.0-snapshot.v20260122110524

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/agent-toolkit

npm i @clerk/agent-toolkit@0.2.9-snapshot.v20260122110524 --save-exact

@clerk/astro

npm i @clerk/astro@3.0.0-snapshot.v20260122110524 --save-exact

@clerk/backend

npm i @clerk/backend@3.0.0-snapshot.v20260122110524 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@3.0.0-snapshot.v20260122110524 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@6.0.0-snapshot.v20260122110524 --save-exact

@clerk/dev-cli

npm i @clerk/dev-cli@1.0.0-snapshot.v20260122110524 --save-exact

@clerk/expo

npm i @clerk/expo@3.0.0-snapshot.v20260122110524 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@1.0.0-snapshot.v20260122110524 --save-exact

@clerk/express

npm i @clerk/express@2.0.0-snapshot.v20260122110524 --save-exact

@clerk/fastify

npm i @clerk/fastify@2.6.9-snapshot.v20260122110524 --save-exact

@clerk/localizations

npm i @clerk/localizations@4.0.0-snapshot.v20260122110524 --save-exact

@clerk/msw

npm i @clerk/msw@0.0.1-snapshot.v20260122110524 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@7.0.0-snapshot.v20260122110524 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@2.0.0-snapshot.v20260122110524 --save-exact

@clerk/react

npm i @clerk/react@6.0.0-snapshot.v20260122110524 --save-exact

@clerk/react-router

npm i @clerk/react-router@3.0.0-snapshot.v20260122110524 --save-exact

@clerk/shared

npm i @clerk/shared@4.0.0-snapshot.v20260122110524 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@1.0.0-snapshot.v20260122110524 --save-exact

@clerk/testing

npm i @clerk/testing@2.0.0-snapshot.v20260122110524 --save-exact

@clerk/ui

npm i @clerk/ui@1.0.0-snapshot.v20260122110524 --save-exact

@clerk/upgrade

npm i @clerk/upgrade@2.0.0-snapshot.v20260122110524 --save-exact

@clerk/vue

npm i @clerk/vue@2.0.0-snapshot.v20260122110524 --save-exact

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@packages/ui/src/components/SessionTasks/index.tsx`:
- Line 58: The ref currentTaskContainer created via useRef<HTMLDivElement>(null)
in SessionTasks is never attached to a DOM node, so currentTaskContainer.current
is always null and accessing offsetHeight yields undefined; either attach this
ref to the DOM element you intend to measure (e.g., add
ref={currentTaskContainer} to the task container div that represents the
"current/previous task" so the offsetHeight read (used to compute minHeight)
becomes valid) or remove the ref and the related minHeight computation entirely
(delete currentTaskContainer, its useRef import, and any code that reads
currentTaskContainer.current.offsetHeight).

In `@packages/ui/src/contexts/components/SessionTasks.ts`:
- Around line 60-62: The constructed navigation path can create a double-slash
when VIRTUAL_ROUTER_BASE_PATH is used and startPath begins with a slash; update
the branch in SessionTasks (the block that checks VIRTUAL_ROUTER_BASE_PATH and
calls navigate) to normalize components before building the URL—either strip a
leading slash from startPath (or trailing slash from basePath) or use a small
path-join helper to concatenate basePath, startPath, and taskEndpoint so
navigate receives a single-clean path (referencing VIRTUAL_ROUTER_BASE_PATH,
startPath, taskEndpoint, and navigate).
🧹 Nitpick comments (2)
packages/ui/src/components/SessionTasks/tasks/TaskSetupMfa/SmsCodeFlowScreen.tsx (1)

72-74: Missing dependency array entries in useEffect.

The effect references prepare which is defined inline and not memoized. While this works for the initial mount pattern, adding prepare or using useCallback would align with React best practices and avoid stale closure issues if the component re-renders.

packages/ui/src/components/SessionTasks/tasks/TaskSetupMfa/TOTPCodeFlowScreen.tsx (1)

271-271: Minor: Comment says "Step 3" but index is 2.

The comment at line 271 says "Step 3" but the wizard step index is 2 (0-indexed). This is a cosmetic inconsistency.

@octoper
Copy link
Member Author

octoper commented Jan 30, 2026

!snapshot

@clerk-cookie
Copy link
Collaborator

Hey @octoper - the snapshot version command generated the following package versions:

Package Version
@clerk/agent-toolkit 0.2.9-snapshot.v20260130165100
@clerk/astro 3.0.0-snapshot.v20260130165100
@clerk/backend 3.0.0-snapshot.v20260130165100
@clerk/chrome-extension 3.0.0-snapshot.v20260130165100
@clerk/clerk-js 6.0.0-snapshot.v20260130165100
@clerk/dev-cli 1.0.0-snapshot.v20260130165100
@clerk/expo 3.0.0-snapshot.v20260130165100
@clerk/expo-passkeys 1.0.0-snapshot.v20260130165100
@clerk/express 2.0.0-snapshot.v20260130165100
@clerk/fastify 2.7.0-snapshot.v20260130165100
@clerk/localizations 4.0.0-snapshot.v20260130165100
@clerk/msw 0.0.1-snapshot.v20260130165100
@clerk/nextjs 7.0.0-snapshot.v20260130165100
@clerk/nuxt 2.0.0-snapshot.v20260130165100
@clerk/react 6.0.0-snapshot.v20260130165100
@clerk/react-router 3.0.0-snapshot.v20260130165100
@clerk/shared 4.0.0-snapshot.v20260130165100
@clerk/tanstack-react-start 1.0.0-snapshot.v20260130165100
@clerk/testing 2.0.0-snapshot.v20260130165100
@clerk/ui 1.0.0-snapshot.v20260130165100
@clerk/upgrade 2.0.0-snapshot.v20260130165100
@clerk/vue 2.0.0-snapshot.v20260130165100

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/agent-toolkit

npm i @clerk/agent-toolkit@0.2.9-snapshot.v20260130165100 --save-exact

@clerk/astro

npm i @clerk/astro@3.0.0-snapshot.v20260130165100 --save-exact

@clerk/backend

npm i @clerk/backend@3.0.0-snapshot.v20260130165100 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@3.0.0-snapshot.v20260130165100 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@6.0.0-snapshot.v20260130165100 --save-exact

@clerk/dev-cli

npm i @clerk/dev-cli@1.0.0-snapshot.v20260130165100 --save-exact

@clerk/expo

npm i @clerk/expo@3.0.0-snapshot.v20260130165100 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@1.0.0-snapshot.v20260130165100 --save-exact

@clerk/express

npm i @clerk/express@2.0.0-snapshot.v20260130165100 --save-exact

@clerk/fastify

npm i @clerk/fastify@2.7.0-snapshot.v20260130165100 --save-exact

@clerk/localizations

npm i @clerk/localizations@4.0.0-snapshot.v20260130165100 --save-exact

@clerk/msw

npm i @clerk/msw@0.0.1-snapshot.v20260130165100 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@7.0.0-snapshot.v20260130165100 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@2.0.0-snapshot.v20260130165100 --save-exact

@clerk/react

npm i @clerk/react@6.0.0-snapshot.v20260130165100 --save-exact

@clerk/react-router

npm i @clerk/react-router@3.0.0-snapshot.v20260130165100 --save-exact

@clerk/shared

npm i @clerk/shared@4.0.0-snapshot.v20260130165100 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@1.0.0-snapshot.v20260130165100 --save-exact

@clerk/testing

npm i @clerk/testing@2.0.0-snapshot.v20260130165100 --save-exact

@clerk/ui

npm i @clerk/ui@1.0.0-snapshot.v20260130165100 --save-exact

@clerk/upgrade

npm i @clerk/upgrade@2.0.0-snapshot.v20260130165100 --save-exact

@clerk/vue

npm i @clerk/vue@2.0.0-snapshot.v20260130165100 --save-exact

@octoper
Copy link
Member Author

octoper commented Feb 2, 2026

!snapshot

@clerk-cookie
Copy link
Collaborator

Hey @octoper - the snapshot version command generated the following package versions:

Package Version
@clerk/agent-toolkit 0.2.9-snapshot.v20260202085507
@clerk/astro 3.0.0-snapshot.v20260202085507
@clerk/backend 3.0.0-snapshot.v20260202085507
@clerk/chrome-extension 3.0.0-snapshot.v20260202085507
@clerk/clerk-js 6.0.0-snapshot.v20260202085507
@clerk/dev-cli 1.0.0-snapshot.v20260202085507
@clerk/expo 3.0.0-snapshot.v20260202085507
@clerk/expo-passkeys 1.0.0-snapshot.v20260202085507
@clerk/express 2.0.0-snapshot.v20260202085507
@clerk/fastify 2.7.0-snapshot.v20260202085507
@clerk/localizations 4.0.0-snapshot.v20260202085507
@clerk/msw 0.0.1-snapshot.v20260202085507
@clerk/nextjs 7.0.0-snapshot.v20260202085507
@clerk/nuxt 2.0.0-snapshot.v20260202085507
@clerk/react 6.0.0-snapshot.v20260202085507
@clerk/react-router 3.0.0-snapshot.v20260202085507
@clerk/shared 4.0.0-snapshot.v20260202085507
@clerk/tanstack-react-start 1.0.0-snapshot.v20260202085507
@clerk/testing 2.0.0-snapshot.v20260202085507
@clerk/ui 1.0.0-snapshot.v20260202085507
@clerk/upgrade 2.0.0-snapshot.v20260202085507
@clerk/vue 2.0.0-snapshot.v20260202085507

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/agent-toolkit

npm i @clerk/agent-toolkit@0.2.9-snapshot.v20260202085507 --save-exact

@clerk/astro

npm i @clerk/astro@3.0.0-snapshot.v20260202085507 --save-exact

@clerk/backend

npm i @clerk/backend@3.0.0-snapshot.v20260202085507 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@3.0.0-snapshot.v20260202085507 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@6.0.0-snapshot.v20260202085507 --save-exact

@clerk/dev-cli

npm i @clerk/dev-cli@1.0.0-snapshot.v20260202085507 --save-exact

@clerk/expo

npm i @clerk/expo@3.0.0-snapshot.v20260202085507 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@1.0.0-snapshot.v20260202085507 --save-exact

@clerk/express

npm i @clerk/express@2.0.0-snapshot.v20260202085507 --save-exact

@clerk/fastify

npm i @clerk/fastify@2.7.0-snapshot.v20260202085507 --save-exact

@clerk/localizations

npm i @clerk/localizations@4.0.0-snapshot.v20260202085507 --save-exact

@clerk/msw

npm i @clerk/msw@0.0.1-snapshot.v20260202085507 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@7.0.0-snapshot.v20260202085507 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@2.0.0-snapshot.v20260202085507 --save-exact

@clerk/react

npm i @clerk/react@6.0.0-snapshot.v20260202085507 --save-exact

@clerk/react-router

npm i @clerk/react-router@3.0.0-snapshot.v20260202085507 --save-exact

@clerk/shared

npm i @clerk/shared@4.0.0-snapshot.v20260202085507 --save-exact

@clerk/tanstack-react-start

npm i @clerk/tanstack-react-start@1.0.0-snapshot.v20260202085507 --save-exact

@clerk/testing

npm i @clerk/testing@2.0.0-snapshot.v20260202085507 --save-exact

@clerk/ui

npm i @clerk/ui@1.0.0-snapshot.v20260202085507 --save-exact

@clerk/upgrade

npm i @clerk/upgrade@2.0.0-snapshot.v20260202085507 --save-exact

@clerk/vue

npm i @clerk/vue@2.0.0-snapshot.v20260202085507 --save-exact

@octoper octoper removed the blocked label Feb 2, 2026
Copy link
Member

@nikosdouvlis nikosdouvlis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a few questions

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
`@packages/ui/src/components/SessionTasks/tasks/TaskSetupMfa/SmsCodeFlowScreen.tsx`:
- Around line 33-39: The boolean expression for hasOtherIdentifications accesses
user.username without optional chaining and can throw in strict mode; update the
check to use optional chaining like the other checks (change user.username !==
null to user?.username !== null) inside the hasOtherIdentifications computation
so it safely handles user being null/undefined.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@packages/localizations/src/nl-BE.ts`:
- Around line 367-373: The nl-BE localization is missing three nested strings
under taskSetupMfa which cause runtime lookups to fail; add Dutch translations
for taskSetupMfa.badge (map to something like "Tweestapsverificatie instellen"),
taskSetupMfa.signOut.actionLink (translate "Sign out" to "Afmelden") and
taskSetupMfa.signOut.actionText (translate "Signed in as {{identifier}}" to
"Aangemeld als {{identifier}}") in the nl-BE file, and leave or comment on the
existing form_password_or_identifier_incorrect discrepancy (en-US undefined vs
nl-BE translated) if that inconsistency is intentional.
🧹 Nitpick comments (1)
packages/localizations/src/es-UY.ts (1)

869-872: Minor voseo inconsistency: "Únete" → "Unite"

The file consistently uses voseo (e.g., "Ingresá", "Agregá", "Revisá"), but this string uses "Únete" (tú imperative). For consistency with Uruguayan Spanish, consider changing to "Unite por invitación."

Suggested fix
     organizationAlreadyExists:
-      'Ya existe una organización para el nombre de empresa detectado ({{organizationName}}) y {{organizationDomain}}. Únete por invitación.',
+      'Ya existe una organización para el nombre de empresa detectado ({{organizationName}}) y {{organizationDomain}}. Unite por invitación.',

@octoper octoper merged commit f284c3d into main Feb 3, 2026
40 checks passed
@octoper octoper deleted the octoper/setup-mfa-task branch February 3, 2026 13:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants